package org.gpswalker.sys.server.users;

import java.util.Hashtable;
import java.util.List;
import java.util.Set;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.NotPersistent;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import org.gpswalker.sys.server.components.GpxTrack;
import org.gpswalker.sys.server.misc.Logger;
import org.gpswalker.sys.server.misc.PMF;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserServiceFactory;

/**
 * This class is a good place to implement key-value coding.
 * Thus the users of this class will not have to know what 
 * fields a user can have, they will be able to get the list of those
 * and to access them correspondingly.
 * @author dtv
 *
 */
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class StoredUser {

    /* non-stored members */
    
    @NotPersistent
    private User googleUser;
    @NotPersistent
    private boolean anonymous = true;
    @NotPersistent
    private boolean isOurs = false;
    
    @Persistent
    public Hashtable<String, String> typesAndTrackSets;
    
/* constructor from cms user class */
    public StoredUser(User gUser) {
        if (gUser == null) {
            return;
        }
        
        
        if (typesAndTrackSets == null) {
            typesAndTrackSets = new Hashtable<String,String>();
            typesAndTrackSets.put("Hello", "Fitst String.");
        } else {
            typesAndTrackSets.put("Hello", "Second string");
        }
        
        
        
        googleUser = gUser;
        anonymous = false;
        
        PersistenceManager pm = PMF.getManager();
        Query q = pm.newQuery(StoredUser.class);

        q.setFilter("email == emailParam");
        q.declareParameters("String emailParam");

        User u = UserServiceFactory.getUserService().getCurrentUser();
        if (u != null) {
            List<StoredUser> l = (List<StoredUser>) q.execute(u.getEmail());

            Logger.log(null, "The number of elements in the list is "
                    + l.size());
            if (l.size() > 0) {
        	isOurs = true;
            }
        }
    }
    
    /* *******************************************************************
     * 
     * these are the methods from Google's User class
     * 
     * *******************************************************************
     */

    // int compareTo (CmsUser u) {

    public String getAuthDomain() {
        return googleUser.getAuthDomain();
    }

    public String getEmail() {
        return googleUser.getEmail();
    }

    public String getNickname() {
        return googleUser.getNickname();
    }

    public String getUserId() {
        return googleUser.getUserId();
    }

    @Override
    public String toString() {
        return "CmsUser" + googleUser.toString();
    }
    
    public static boolean isAdmin() {
        return (false /*user().isOurs*/);
    }

    public boolean isAnonymous() {
        return anonymous;
    }
    
    public boolean isOurs() {
        return isOurs;
    }

    
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key id;

    @Persistent
    private String email;

    @Persistent
    private String name;
    
    @Persistent
    private Set<GpxTrack> tracks;

//    private StoredUser() {
//    }

//    public StoredUser(User u) {
//	email = u.getEmail();
//    }

    // Setters
    public void setName(String aName) {
	if (aName != null) {
	    name = aName;
	}
    }

    // Getters
    public Key id() {
	return id;
    }

    public String idString() {
	return KeyFactory.keyToString(id);
    }

    public String email() {
	return email;
    }

    public String name() {
	return name;
    }

    public boolean isRegistered() {
	return (id != null);
    }
    
    public void addTrack(GpxTrack t) {
	tracks.add(t);
    }

}
